#include <array>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;
#include <chrono>
#include <cstdio>
void MyTimer(int type, const char *info = nullptr) {
  static std::chrono::steady_clock::time_point start;
  if (type == 0) {
    start = std::chrono::steady_clock::now();
    printf("Begin %s\n", info);
    return;
  } else {
    auto end = std::chrono::steady_clock::now();
    auto dt =
        std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
    printf("End %s, time taken=%lf\n", info, dt.count());
  }
}

#define NDEBUG
using real_t = double;
struct Point {
  real_t p[3];
  real_t &operator[](int i) noexcept {
    assert(-1 < i && i < 3);
    return p[i];
  }
  const real_t &operator[](int i) const noexcept {
    assert(-1 < i && i < 3);
    return p[i];
  }
  real_t &x() noexcept { return p[0]; }
  real_t &y() noexcept { return p[1]; }
  real_t &z() noexcept { return p[2]; }
  const real_t &x() const noexcept { return p[0]; }
  const real_t &y() const noexcept { return p[1]; }
  const real_t &z() const noexcept { return p[2]; }
  real_t *data() noexcept { return p; }
  const real_t *data() const noexcept { return p; }
  int size() const noexcept { return 3; }

  Point &operator/=(const real_t val) {
    p[0] /= val;
    p[1] /= val;
    p[2] /= val;
    return *this;
  }
  Point &operator+=(const Point &varp) {
    p[0] += varp[0];
    p[1] += varp[1];
    p[2] += varp[2];
    return *this;
  }
};

// 还是 arr1 快   多维情况下还是原生数组快  用双动态数组
int main(int argc, char *argv[]) {
  if (argc != 2) {
    cerr << "./a.out num_elems" << endl;
    exit(EXIT_FAILURE);
  }
  const int n0 = atoi(argv[1]) * 10000000;
  const int n{4};

  vector<int> nelem(n);
  for (int i = 0; i < nelem.size(); ++i) {
    nelem[i] = n0 + 10000;
  }
  int tmp;
  cout << "hello" << endl;

  Point *arr1[4];
  for (int i = 0; i < nelem.size(); ++i) {
    arr1[i] = (Point *)malloc(sizeof(Point) * nelem[i]);
  }
  MyTimer(0, "arr1");

  for (int i = 0; i < n; ++i) {
    tmp = nelem[i];
    // 要不要下面这行没啥改变  不用要好一些
    Point *parr = arr1[i];
    for (int j = 0; j < tmp; ++j) {
      parr[j].x() = i + j * 2.0;
      parr[j].x() = i + j * 3.0;
      parr[j].x() = i + j * 4.0;
    }
  }
  MyTimer(1, "arr1");

  vector<Point> vec1[4];
  for (int i = 0; i < nelem.size(); ++i) {
    vec1[i].reserve(nelem[i]);
  }
  MyTimer(0, "vec1");
  for (int i = 0; i < n; ++i) {
    tmp = nelem[i];
    vector<Point> &tvec{vec1[i]};
    for (int j = 0; j < tmp; ++j) {
      Point &p{tvec[j]};
      p.x() = i + j * 2.0;
      p.y() = i + j * 3.0;
      p.z() = i + j * 4.0;
    }
  }
  MyTimer(1, "vec1");

  return 0;
}